package edu.hawaii.ics414.blackjack.card;

/**
 * A basic playing card.
 * This class is designed to be immutable.
 * 
 * @author Branden Ogata
 *
 */

public class Card
{
  /**
   * The suit of this Card.
   * 
   */
  private Suit suit;
  
  /**
   * The rank of this Card.
   * 
   */
  private Rank rank;
  
  /**
   * Creates a new Card.
   * 
   * @param suit The Suit of the Card to create.
   * @param rank The rank of the Card to create.
   * 
   */
  
  public Card(Suit suit, Rank rank)
  {
    this.suit = suit;
    this.rank = rank;
  }

  /**
   * Returns the suit of this Card.
   *
   * @return suit The Suit containing the suit of this Card.
   *
   */
  
  public Suit getSuit()
  {
    return this.suit;
  }

  /**
   * Returns the rank of this Card.
   *
   * @return rank The Rank containing the rank of this Card.
   *
   */
  
  public Rank getRank()
  {
    return this.rank;
  }
  
  /**
   * Returns the value of this Card.
   * 
   * @return value An int containing the numeric value of this Card.
   *               Aside from the numeric cards, Aces count as 1 or 11, while Jack, Queen, and King
   *               are 10 each; since it is impossible to return multiple values, Aces will have
   *               a value of 1, leaving the calling class to determine which value to use.
   * 
   */
  
  public int getValue()
  {
    int value = 0;
    
    switch (this.rank)
    {
      case ACE:
        value = 1;
        break;
      case TWO:
        value = 2;
        break;
      case THREE:
        value = 3;
        break;
      case FOUR:
        value = 4;
        break;
      case FIVE:
        value = 5;
        break;
      case SIX:
        value = 6;
        break;
      case SEVEN:
        value = 7;
        break;
      case EIGHT:
        value = 8;
        break;
      case NINE:
        value = 9;
        break;
      case TEN:
        value = 10;
        break;
      case JACK:
      case QUEEN: 
      case KING: 
        value = 10;
        break;
      default: 
        break;
    }
    
    return value;
  }
  
  /**
   * Checks if this Card is equal to another Object.
   * 
   * @param obj The Object to compare this Card to.
   * 
   * @return isEqual A boolean that is true if this Card is equal to the parameter,
   *                                   false otherwise.
   *                                   
   */
  
  @Override 
  public boolean equals(Object obj)
  {
    boolean isEqual = false;
    
    // Check if the parameter is this Card
    if (this == obj)
    {
      isEqual = true;
    }
    // Check if the object is an instance of Card
    else if (obj instanceof Card)
    {
      Card temp = (Card) obj;
      
      // The two are equal iff their suit and rank are the same
      if ((this.suit.equals(temp.getSuit())) && (this.rank.equals(temp.getRank())))
      {
        isEqual = true;
      }
    }
    
    
    return isEqual;
  }
  
  /**
   * Returns a hashcode based on this Card instance.
   *
   * @return result An int equal to the hashcode for this Card.
   *
   */
   
  @Override
  public int hashCode()
  {
    int result = 23;
    int combination = this.suit.hashCode() + this.rank.hashCode();
    result = 29 * result + combination;
    return result;
  }  
  
  /**
   * Returns a String representation of this Card.
   * This is in the format [rank][suit].
   * 
   * @return A String containing the rank and suit of this Card.
   * 
   */
  
  @Override
  public String toString()
  {
    return this.rank.toString() + this.suit.toString();
  }
}
